﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using ProjectPigs.Scenes;
using ProjectPigs;

namespace ProjectPigs.Assets
{
    class AssetImporter
    {

        static List<GeneralAsset> assets = new List<GeneralAsset>();
        static GeneralAsset tempAsset;
        static int itemsImported = 0;

        public static Map importMap(String mapFileName, Model [] allModels)
        {


            //go through allModels, extract modelMeshes
            //add them to Map (pos, rot, scale)
            String URL = Directory.GetCurrentDirectory()+"\\Maps\\";
            int skippedLines = 0;

            try
            {
                using (StreamReader sr = new StreamReader(URL + mapFileName + ".map"))
                {
                    Console.WriteLine("Reading map [" + mapFileName + "] from directory " + URL);
                    String line;
                    // Read and display lines from the file until the end of
                    // the file is reached.
                    while ((line = sr.ReadLine()) != null)
                    {
                         tempAsset = new GeneralAsset();

                        try
                        {
                            parseLine(line, ref tempAsset);
                        }
                        catch (Exception e)
                        {
                            skippedLines++;
                            continue ;
                        }
                        itemsImported++;
                        assets.Add(tempAsset);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Importing map [" + mapFileName + "].. FAILED.");
                Console.WriteLine("Exception: " + e.Message);

                return new Map(mapFileName, assets.ToArray());
            }

            if (skippedLines > 0)
            {
                Console.WriteLine("WARNING: invalid asset data found, skipped assets: " + skippedLines);
            }

            Console.WriteLine("Importing map [" + mapFileName + "].. OK. Objects read: " + itemsImported);
            return new Map(mapFileName, assets.ToArray());
        }

        private static void parseLine(String line, ref GeneralAsset asset)
        {
            int index = 0;
            int subindex = 0;
            bool reading = false;


                char[] charArray = line.ToCharArray();
                List<char> catche = new List<char>();
 
         
            

            foreach (char c in charArray)
            {

                if (!reading)
                {
                    //start reading
                    if (c == '[') { reading = true; catche.Clear(); }
                }
                else if (reading)
                {
                    //Stop reading and step to next segment
                    if (c == ']') {
                     
                            assignCatche(catche.ToArray(), asset, index, subindex);
                        
                        reading = false; 
                        index++; }
                    
                    else if (c == ' ') { } // ignore for now
                }

                if (reading)
                {
                    if(c != ' ' && c!= '[') catche.Add(c); //skip spaces
                }
            }


        }

        private static  String[] parseSubCatche(char[] catche, int lastIndex)
        {

            List<char> subC = new List<char>();
            List<String> strings = new List<String>();
            int index = 0;
            int eachStep = 0;

            foreach (char c in catche)
            {
                if (c == ',' )
                {
                    
                    strings.Add(new String(subC.ToArray()));
                    index++;
                    subC.Clear();
                }
                else if (eachStep == lastIndex)
                {
                    subC.Add(c);    //adding last digit
                    strings.Add(new String(subC.ToArray()));
                    subC.Clear();
                }
                else if (c != ' ')
                {
                    subC.Add(c);
                }
                eachStep++;
            }

            return strings.ToArray(); 
        }

        private static void assignCatche(char[] catche, GeneralAsset asset, int index, int subindex)
        {
           

            switch (index)
            {
                case AssetReadOrder.TYPE: asset.Type = new String(catche); break;
                case AssetReadOrder.GROUP: asset.Group = new String(catche); break;
                case AssetReadOrder.NAME: asset.Name = new String(catche); break;
                case AssetReadOrder.TAG: asset.Tag = new String(catche); break;
                case AssetReadOrder.LAYER:  asset.Layer = Int32.Parse(new String(catche));  break;
                case AssetReadOrder.TRANSFORM:

                    int lastIndex = catche.Length - 1;
                    String[] tokens = parseSubCatche(catche, lastIndex);
                    for (int i = 0; i < tokens.Length; i++)
                    {
                        switch (i)
                        {
                            case 0: asset.Transform.setPosition_X(float.Parse(tokens[i])); break;
                            case 1: asset.Transform.setPosition_Y(float.Parse(tokens[i])); break;
                            case 2: asset.Transform.setPosition_Z(float.Parse(tokens[i])); break;
                            case 3: asset.Transform.setRotation_X(float.Parse(tokens[i])); break;
                            case 4: asset.Transform.setRotation_Y(float.Parse(tokens[i])); break;
                            case 5: asset.Transform.setRotation_Z(float.Parse(tokens[i])); break;
                            case 6: asset.Transform.setScale_X(float.Parse(tokens[i])); break;
                            case 7: asset.Transform.setScale_Y( float.Parse(tokens[i])); break;
                            case 8: asset.Transform.setScale_Z( float.Parse(tokens[i])); break;
                            default: Console.WriteLine("WARNING: SubIndex out of bounds " + subindex); break;
                        }
                    }
                    break;
                case AssetReadOrder.TYPE_SPECIFIC:
                    break;

            }



        }
    }
}
